<template>
  <div>
    <content-panel
      ref="content"
      title="定时任务"
      :ops="{add:'system:job:add', update: 'system:job:edit', delete: 'system:job:delete', export: 'system:job:export'}"
      search-label-width="88px"
      :search-props="searchProps"
      :table-props="tableProps"
      list-api="getJobs"
      get-api="getJob"
      delete-api="deleteJob"
      @handle-add="handleAdd"
      @handle-update="handleUpdate"
      :import-and-export="{ exportUrl: '/quartz/job/export' }"
    >
      <template #ops>
        <el-col :span="1.5">
          <el-button
            v-has-perm="['system:job:query']"
            type="info"
            plain
            :icon="Operation"
            size="small"
            @click="handleJobLog"
          >全部日志
          </el-button>
        </el-col>
      </template>

      <template #jobGroup="scope">
        <dict-tag :options="$dict.job_group" :value="scope.row.jobGroup" />
      </template>

      <template #executeStatus="scope">
        <el-switch
          v-model="scope.row.executeStatus"
          active-value="0"
          inactive-value="1"
          @click="handleStatusChange(scope.row)"
        />
      </template>


      <template #operate="scope">
        <div class="operation-buttons">
          <el-button
            v-has-perm="['system:job:edit']"
            size="small"
            link
            :icon="Edit"
            @click="handleUpdate(scope.row)"
          >修改
          </el-button>
          <el-button
            v-has-perm="['system:job:delete']"
            size="small"
            link
            :icon="Delete"
            style="color: #F56C6C"
            @click="handleDelete(scope.row)"
          >删除
          </el-button>
          <el-dropdown
            v-has-perm="['system:job:changeStatus', 'system:job:query']"
            size="small"
            @command="(command) => handleCommand(command, scope.row)"
          >
            <el-button
              size="small"
              link
              :icon="DArrowRight"
              style="color: #23cf69"
            >更多
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item
                  command="handleRun"
                  :icon="CaretRight"
                >执行一次
                </el-dropdown-item>
                <el-dropdown-item
                  command="handleView"
                  :icon="View"
                >任务详细
                </el-dropdown-item>
                <el-dropdown-item
                  command="handleJobLog"
                  :icon="Operation"
                >调度日志
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </template>
    </content-panel>

    <!-- 添加或修改定时任务对话框 -->
    <el-dialog
      v-model="open"
      :title="title"
      width="800px"
      append-to-body
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="任务名称" prop="jobName">
              <el-input v-model="form.jobName" placeholder="请输入任务名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务分组" prop="jobGroup">
              <el-select v-model="form.jobGroup" placeholder="请选择">
                <el-option
                  v-for="dict in $dict.job_group"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item prop="invokeTarget">
              <template #label>
                调用方法
                <el-tooltip placement="top">
                  <template #content>
                    Bean调用示例：ryTask.ryParams('ry')
                    <br>Class类调用示例：com.ruoyi.quartz.task.RyTask.ryParams('ry')
                    <br>参数说明：支持字符串，布尔类型，长整型，浮点型，整型
                  </template>
                  <el-icon>
                    <question-filled />
                  </el-icon>
                </el-tooltip>
              </template>
              <el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="cron表达式" prop="cronExpression">
              <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
                <template #append>
                  <el-button type="primary" @click="handleShowCron">
                    生成表达式
                    <el-icon>
                      <Timer />
                    </el-icon>
                  </el-button>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="执行策略" prop="misfirePolicy">
              <el-radio-group v-model="form.misfirePolicy" size="small">
                <el-radio-button value="1">立即执行</el-radio-button>
                <el-radio-button value="2">执行一次</el-radio-button>
                <el-radio-button value="3">放弃执行</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否并发" prop="concurrent">
              <el-radio-group v-model="form.concurrent" size="small">
                <el-radio-button :value="true">允许</el-radio-button>
                <el-radio-button :value="false">禁止</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-radio-group v-model="form.executeStatus">
                <el-radio
                  v-for="dict in $dict.job_status"
                  :key="dict.value"
                  :value="dict.value"
                >{{ dict.label }}
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog
      v-model="openCron"
      title="Cron表达式生成器"
      append-to-body
      destroy-on-close
      class="scrollbar"
    >
      <crontab :expression="expression" @hide="openCron = false" @fill="crontabFill" />
    </el-dialog>

    <!-- 任务日志详细 -->
    <el-dialog
      v-model="openView"
      title="任务详细"
      width="700px"
      append-to-body
    >
      <el-form ref="viewFormRef" :model="form" label-width="120px" size="small">
        <el-row>
          <el-col :span="12">
            <el-form-item label="任务编号：">{{ form.id }}</el-form-item>
            <el-form-item label="任务名称：">{{ form.jobName }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务分组：">{{ jobGroupFormat(form) }}</el-form-item>
            <el-form-item label="创建时间：">{{ form.createTime }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="cron表达式：">{{ form.cronExpression }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="下次执行时间：">{{ parseTime(form.nextValidTime) }}</el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="调用目标方法：">{{ form.invokeTarget }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务状态：">
              <div v-if="form.executeStatus === '0'">正常</div>
              <div v-else-if="form.executeStatus === '1'">失败</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否并发：">
              <div v-if="form.concurrent">允许</div>
              <div v-else>禁止</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="执行策略：">
              <div v-if="form.misfirePolicy === '0'">默认策略</div>
              <div v-else-if="form.misfirePolicy === '1'">立即执行</div>
              <div v-else-if="form.misfirePolicy === '2'">执行一次</div>
              <div v-else-if="form.misfirePolicy === '3'">放弃执行</div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="openView = false">关 闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {Operation, DArrowRight, View, QuestionFilled, Timer, CaretRight, Edit, Delete,} from '@element-plus/icons-vue'
import {parseTime, selectDictLabel} from "@/utils/index.js"

const router = useRouter()

const content = ref(null)
const formRef = ref(null)
const viewFormRef = ref(null)


const title = ref('')
const open = ref(false)
const openView = ref(false)
const openCron = ref(false)
const expression = ref('')

// 表单数据
const form = ref({
  id: undefined,
  jobName: undefined,
  jobGroup: undefined,
  invokeTarget: undefined,
  cronExpression: undefined,
  misfirePolicy: 1,
  concurrent: false,
  executeStatus: '0'
})

// 表格配置
const tableProps = [
  {label: '任务编号', prop: 'id'},
  {label: '任务名称', prop: 'jobName'},
  {label: '任务组名', prop: 'jobGroup', type: 'jobGroup'},
  {label: '调用目标字符串', prop: 'invokeTarget'},
  {label: 'cron执行表达式', prop: 'cronExpression'},
  {label: '状态', prop: 'executeStatus', type: 'executeStatus'},
  {label: '操作', type: 'operate'}
]

// 校验规则
const rules = {
  jobName: [
    {required: true, message: '任务名称不能为空', trigger: 'blur'}
  ],
  invokeTarget: [
    {required: true, message: '调用目标字符串不能为空', trigger: 'blur'}
  ],
  cronExpression: [
    {required: true, message: 'cron执行表达式不能为空', trigger: 'blur'}
  ]
}


const searchProps = ref([
  {label: '任务名称', prop: 'jobName', type: 'input'},
  {label: '任务组名', prop: 'jobGroup', type: 'select', options: $dict.job_group},
  {label: '任务状态', prop: 'executeStatus', type: 'select', options: $dict.job_status}
])

// 方法
function jobGroupFormat(row) {
  return selectDictLabel($dict.job_group, row.jobGroup)
}

const cancel = () => {
  open.value = false
  reset()
}

const reset = () => {
  form.value = {
    id: undefined,
    jobName: undefined,
    jobGroup: undefined,
    invokeTarget: undefined,
    cronExpression: undefined,
    misfirePolicy: 1,
    concurrent: false,
    executeStatus: '0'
  }
  formRef.value?.resetFields()
}

const handleCommand = (command, row) => {
  switch (command) {
    case 'handleRun':
      handleRun(row)
      break
    case 'handleView':
      handleView(row)
      break
    case 'handleJobLog':
      handleJobLog(row)
      break
  }
}

const handleStatusChange = (row) => {
  const text = row.executeStatus === '0' ? '启用' : '停用'
  $xl.modal.confirm(`确认要"${text}""${row.jobName}"任务吗？`).then(() => {
    $xl.apis.changeJobExecute({
      params: {
        id: row.id,
        executeStatus: row.executeStatus
      }
    }).then(() => {
      $xl.modal.msgSuccess(text + '成功')
    })
  }).catch(() => {
    row.executeStatus = row.executeStatus === '0' ? '1' : '0'
  })
}

const handleRun = (row) => {
  $xl.modal.confirm(`确认要立即执行一次"${row.jobName}"任务吗？`).then(() => {
    $xl.apis.runJob({
      params: {
        id: row.id,
        jobGroup: row.jobGroup
      }
    }).then(() => {
      $xl.modal.msgSuccess('执行成功')
    })
  }).catch(() => {
  })
}

const handleView = (row) => {
  $xl.apis.getJob({
    jointUrl: '/' + row.id
  }).then(response => {
    form.value = response.data
    openView.value = true
  })
}

const handleShowCron = () => {
  expression.value = form.value.cronExpression
  openCron.value = true
}

const crontabFill = (value) => {
  form.value.cronExpression = value
}

const handleJobLog = (row) => {
  const jobId = row?.id || 0
  router.push({path: '/common/system/job/job-log/index', query: {jobId}})
}

const handleAdd = () => {
  reset()
  open.value = true
  title.value = '添加任务'
}

const handleUpdate = (row) => {
  reset()
  const jobId = row.id || content.value.getSelectedIds()
  $xl.apis.getJob({
    jointUrl: '/' + jobId
  }).then(response => {
    form.value = response.data
    open.value = true
    title.value = '修改任务'
  })
}

const handleDelete = (row) => {
  $xl.modal.confirm(`确认要删除"${row.jobName}"任务吗？`).then(() => {
    $xl.apis.deleteJob({
      jointUrl: '/' + row.id || content.value.getSelectedIds()

    }).then(() => {
      $xl.modal.msgSuccess('删除成功')
      content.value.getList()
    })
  }).catch(() => {
  })
}

const submitForm = async () => {
  formRef.value.validate(valid => {
    if (valid) {
      if (form.value.id !== undefined) {
        $xl.apis.updateJob({params: form.value}).then(() => {
          $xl.modal.msgSuccess('修改成功')
          open.value = false
          content.value.getList()
        })
      } else {
        $xl.apis.saveJob({params: form.value}).then(() => {
          $xl.modal.msgSuccess('新增成功')
          open.value = false
          content.value.getList()
        })
      }
    }
  })
}
</script>


<style lang="scss" scoped>
.operation-buttons {
  display: flex;
}
</style>
